package com.mxprojects.gui
{
	import com.mxprojects.constructors.ButtonSmall;
	import com.mxprojects.constructors.InputConstructor;
	import com.mxprojects.constructors.ProgressBar;
	import com.mxprojects.constructors.SimpleTextField;
	import com.mxprojects.io.BoardCookie;
	import com.mxprojects.io.Config;
	import com.mxprojects.io.CustomEvent;
	import com.mxprojects.io.FileUploader;
	import com.mxprojects.io.ServerHandler;
	import com.mxprojects.language.Language;
	import com.mxprojects.language.Word;
	
	import flash.display.MovieClip;
	import flash.events.DataEvent;
	import flash.events.IEventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.MouseEvent;
	import flash.events.ProgressEvent;
	import flash.net.FileReference;
	import flash.net.URLVariables;
	
	public class FileItem extends MovieClip implements IEventDispatcher
	{
		public static const REMOVED_FILE:String = "REMOVED_FILE";
		public static const ADDED_FILE:String = "ADDED_FILE";
		
		private const TEXT_SIZE:int = 10;
		private const TEXT_FONT:String = "Arial";
		private const TEXT_COLOUR:uint = 0x000000;
		private const TEXT_BOLD:Boolean = true;
		private const MAX_DESCRIPTION_CHARS:int = 100;
		
		//constants for upload/remove results
		private const ERROR_LOGIN:String = "loginError";
		private const ERROR_FILE_DIMENSION:String = "fileDimensionError";
		private const ERROR_FILE_TYPE:String = "fileTypeError";
		private const ERROR_UPLOAD_FAIL:String = "uploadFail";
		private const ERROR_REMOVE_FAIL:String = "removeFail";
		private const ERROR_MISSING_FILE:String = "missingFile";
		private const SUCCESS:String = "success";
		
		private var doProgress:Boolean;
		private var showDescription:Boolean;
		private var showStageOnErrorClose:Boolean;
		private var finishFunction:Function;
		private var uploader:FileUploader;
		private var setWidth:int;
		private var id:int;
		
		private var progress:ProgressBar;
		private var description:InputConstructor;
		private var remove:ButtonSmall;
		private var subDirectory:String;
		
		private var imageNameForServer:String;
		private var serverHandler:ServerHandler = new ServerHandler();
		
		public function FileItem(file:FileReference, fileUploader:FileUploader, progressWidth:int, subDirectory:String, showProgress:Boolean = true, showDescription:Boolean = true, showStageOnErrorClose:Boolean = false){
			this.showDescription = showDescription;
			this.showStageOnErrorClose = showStageOnErrorClose;
			this.subDirectory = subDirectory;
			
			doProgress = showProgress;
			uploader = fileUploader;
			setWidth = progressWidth;
			
			//setup the progress bar
			progress = new ProgressBar(file.size, setWidth);
			setupListeners(file);
			addChild(progress);

			//give this thing it's own name
			setID(uploader.totalFilesSelected);
		}
		
		public function setID(idNumber:int):void {
			id = idNumber;
			name = "file" + id;
		}
		
		public function getID():int {
			return id;
		}
		
		public function removeFile(event:MouseEvent = null):void {
			var dataToSend:Object = new Object();
			dataToSend.username = BoardCookie.getUser();
			dataToSend.password = BoardCookie.getPassword();
			dataToSend.fileName = imageNameForServer;
			dataToSend.actionType = FileUploader.REMOVE_FILE;
			dataToSend.abImgDir = Config.ABSOLUTE_INSTALL_PATH + Config.IMAGE_DIRECTORY + subDirectory;
			
			serverHandler.transmitData("transfer.php", dataToSend);
			serverHandler.listenForData(removeFromUI);
			
			//disable the remove button
			remove.enabled = false;
		}
		
		private function setupListeners(file:FileReference):void {
			//listen to the file and update our progress
			if(doProgress){
				file.addEventListener(ProgressEvent.PROGRESS, updateProgress, false, 0, true);
				progress.visible = true;
			}else{
				progress.visible = false;
			}
			file.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, done, false, 0, true);
			file.addEventListener(IOErrorEvent.IO_ERROR, fileError, false, 0, true);
		}
		
		private function updateProgress(event:ProgressEvent):void {
			//update the progress bar
			progress.update(event.bytesLoaded);
			
			//update the current data transfered
			/*
			progress[event.target.name] = Math.ceil(event.bytesLoaded/1024);
			
			//show the progress
			currentDataTransfered = 0;
			for(var i:int = 0; i < selectedFiles.length; i++){
				currentDataTransfered += progress[selectedFiles[i].name];
			}
			trace(currentDataTransfered + "/" + totalDataToTransfer);
			*/
		}
		
		private function done(event:DataEvent):void {
			//let someone know that we've finished up here			
			var imageData:URLVariables = new URLVariables();
			imageData.decode(event.data);
			
			//take the number of files uploaded down unless we are successful
			uploader.totalFilesSelected--;
			
			//check the output
			switch(imageData.output){
				case ERROR_LOGIN:
					DefaultDialog.show(Language.main(Word.ERROR_LOGIN_INVALID), showStageOnErrorClose);
				break;
				
				case ERROR_FILE_DIMENSION:
					DefaultDialog.show(Language.main(Word.ERROR_FILE_DIMENSIONS) + " <b>" + imageData.maxWidth + " x " + imageData.maxHeight + "</b>", showStageOnErrorClose);
				break;
				
				case ERROR_FILE_TYPE:
					DefaultDialog.show("<b>" + imageData.name + "</b><br><br>" + Language.main(Word.ERROR_FILE_TYPE), showStageOnErrorClose);
				break;
				
				case ERROR_UPLOAD_FAIL:
					DefaultDialog.show("<b>" + imageData.name + "</b><br><br>" + Language.main(Word.ERROR_UPLOAD_FAIL), showStageOnErrorClose);
				break;
				
				case ERROR_MISSING_FILE:
					DefaultDialog.show(Language.main(Word.ERROR_FILE_MISSING), showStageOnErrorClose);
				break;
				
				case SUCCESS:
					//set the number of files to where it was
					uploader.totalFilesSelected++;
					
					//set the vars from the server
					imageNameForServer = imageData.salt + FileUploader.IMAGE_SPACER + imageData.name;
					
					//create a remove button
					remove = new ButtonSmall(Language.main(Word.REMOVE), removeFile);
					
					//put the name of the file there
					if(subDirectory != Config.AVATAR_UPLOAD_SUB_DIRECTORY){
						var fileLabel:SimpleTextField = new SimpleTextField("<span class=\"formFileUpload\">" + 
																			Language.main(Word.IMAGE) + InputConstructor.LABEL_SEPARATOR + 
																			"</span>", 1, true);
						var fileName:SimpleTextField = new SimpleTextField("<span class=\"formFileUpload\">" + imageData.name + "</span>");
						fileName.x = fileLabel.width;
						
						//show them
						addChild(fileLabel);
						addChild(fileName);
						
						//move the button
						remove.y = Math.round(fileName.height);
					}
					
					if(showDescription){
						//create the description and remove button
						description = new InputConstructor("<span class=\"formFileUpload\">" + Language.main(Word.DESCRIPTION) + "</span>", 
														   "", uploader.totalFilesSelected + 3, false, 1, "formInputLabel", "formInput", 
														   MAX_DESCRIPTION_CHARS);
						description.y = Math.round(fileName.height);
						description.changeWidth(setWidth/2);
						addChild(description);
						
						//position remove button
						remove.x = Math.round(description.width) + Config.TEXT_PADDING;
						remove.y = description.y + Math.round((description.height/2) - (remove.height/2));
						
						//position the fileLabel
						if(fileLabel.width > description.inputLabel.width){
							//move the description over
							description.x += fileLabel.width - description.inputLabel.width;
						}else{
							//move the fileLabel over
							fileLabel.x += description.inputLabel.width - fileLabel.width;
						}
						
						//make the file name inline with the description box
						fileName.x = description.x + description.inputBox.x;
					}
					
					//add the remove button
					addChild(remove);
					
					//let someone who is listening know
					dispatchEvent(new CustomEvent(ADDED_FILE));
				break;
			}
		}
		
		private function removeFromUI(event:CustomEvent):void {
			//axe it
			var result:Object = event.getServerData();
			
			switch(result.output){
				case ERROR_MISSING_FILE:
					DefaultDialog.show(Language.main(Word.ERROR_FILE_MISSING), showStageOnErrorClose);
				break;
				
				case ERROR_REMOVE_FAIL:
					DefaultDialog.show(Language.main(Word.ERROR_FILE_REMOVE), showStageOnErrorClose);
				break;
				
				case SUCCESS:
					//remove if from the parent and move any others
					for(var i:int = uploader.totalFilesSelected - 1; i > id; i--){
						//move the other ones up
						var fileItem:FileItem = parent.getChildByName("file"+i) as FileItem;
						if(fileItem != null){
							fileItem.setID(i-1);
							fileItem.y -= fileItem.height;
						}
					}
					
					//let someone who is listening know
					dispatchEvent(new CustomEvent(REMOVED_FILE));
					
					//remove this one
					parent.removeChild(this);
					uploader.totalFilesSelected--;
				break;
			}
		}
		
		private function fileError(event:IOErrorEvent):void {
			//this means they don't have write perms
			var showStage:Boolean = false;
			if(MXP3.currentLocation == Word.REGISTER || MXP3.currentLocation == Word.PROFILE){
				showStage = true;
			}
			DefaultDialog.show(event.toString(), showStage);
			uploader.totalFilesSelected--;
		}
		
		public function getFileName():String {
			return imageNameForServer;
		}
		
		public function getDescription():String {
			return description.getValue();
		}

	}
}